package cate.game.activity.mooncake;

import cate.common.table.activity.mooncake.row.MooncakeBossRow;
import cate.common.table.d.*;
import cate.common.util.GameResult;
import cate.game.activity.base.core.SubActivitySingle;
import cate.game.activity.mooncake.msg.MooncakeChallengeDataResp;
import cate.game.activity.mooncake.msg.MooncakeInfoResp;
import cate.game.fight.task.FightTask;
import cate.game.play.part.FightSide;
import cate.game.play.proce.play.PlayPO;
import cate.game.res.MixRes;
import cate.game.role.bag.hero.Hero;
import cate.game.role.farm.IFarm;
import cate.game.role.farm.PlayTimes;
import cate.game.role.fight.FuncPosition;
import cate.game.role.fight.HeroGrid;
import cate.game.role.fight.Position;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashMap;
import java.util.Map;

import static cate.common.table.d.GDFunc.ADVENTURE;

public class MooncakeChallenge extends SubActivitySingle<MooncakeActivity> implements IFarm {
    @NoteField(value = "战斗")
    public boolean fighting;
    @NoteField("key:阵营campId，value：已通关数")
    public Map<Integer, Integer> passMap;
    @NoteField(value = "挑战次数")
    public PlayTimes playTimes;
    @NoteField(value = "当前/最近一次 所挑战的月饼bossID")
    public int curRoomId;
    @NoteField(value = "所有副本已挑战次数，包含扫荡")
    public int challengeTimes;

    @Override
    public void initialize(MooncakeActivity parent) {
        super.initialize(parent);
        if (passMap == null) {
            passMap = new HashMap<>();
        }
        if (playTimes == null) {
            playTimes = new PlayTimes();
        }
        playTimes.initialize();
        FightTask task = role.getGame().fight.task.getTask(role, getFightFuncId());
        fighting = task != null && !task.invalid();
    }

    @Override
    public void onEnter() {
        super.onEnter();
        FightTask task = role.getGame().fight.task.getTask(role, getFightFuncId());
        fighting = task != null && !task.invalid();
    }

    public void onRoleOpen() {
        for (int camp : GDCamp.Type.getAllCamps(false)) {
            passMap.put(camp, 0);
        }
    }

    public void onRoleEnd() {
        this.fighting = false;
        passMap.clear();
        playTimes.reset();
        curRoomId = 0;
        challengeTimes = 0;
    }

    @Override
    public void onDaySpan(boolean silence) {
        super.onDaySpan(silence);
        playTimes.reset();
    }

    public int getFuncId() {
        switch (curRoomId) {
            case 1:
                return GDFunc.MOONCAKE_C1;
            case 2:
                return GDFunc.MOONCAKE_C2;
            case 3:
                return GDFunc.MOONCAKE_C3;
            case 4:
                return GDFunc.MOONCAKE_C4;
            case 5:
                return GDFunc.MOONCAKE_C5;
            case 6:
                return GDFunc.MOONCAKE_C6;
            default:
                return 0;
        }
    }

    @Override
    public boolean isFighting() {
        return fighting;
    }

    @Override
    public void startFighting() {
        this.fighting = true;
    }

    @Override
    public void endFighting() {
        this.fighting = false;
    }


    @Override
    public int getFightFuncId() {
        return GDFunc.MOONCAKE;
    }

    public void setPassSafe(int roomId,int combatNumPass) {
        int roundPass = passMap.get(roomId);
        if (combatNumPass != roundPass + 1) {
            return;
        }
        roundPass++;
        passMap.put(roomId, roundPass);
    }

    public void noticeUpdate() {
        role.sendNow(new MooncakeChallengeDataResp(this));
    }

    private GameResult<Void> challengeCheck(int roomId, int combatNum, boolean mop) {
        GameResult<Void> r = new GameResult<>();
        if (fighting) {
            return r.fail("当前战斗未结束");
        }

        Integer passNum = passMap.get(roomId);
        if (passNum == null) {
            return r.fail("类型异常");
        }
        MooncakeBossRow combatTpl = role.getGame().table.mooncake.boss.find(roomId, combatNum);
        if (combatTpl == null) {
            return r.fail("模板表中找不到该关卡");
        }
        if (!mop) {
            // 普通挑战模式
            // combatNum 只应该等于 combatNumPass+1
            if (combatNum <= passNum) {
                return r.fail("你已通过该副本，直接扫荡即可");
            }
            if (combatNum > passNum + 1) {
                return r.fail("请先通过前一个关卡");
            }
        } else if (passNum < 1) {
            return r.fail("当前无可扫荡关卡");
        } else {
            // 扫荡模式
            if (combatNum > passNum) {
                return r.fail("尚未通过该副本，请先挑战，然后再扫荡");
            }
        }

        GameResult<Void> checkRes = this.playTimes.available(role, getFightFuncId());
        if (!checkRes.ok()) {
            return r.fail(checkRes);
        }
        return r.success();
    }

    /**
     * 挑战或扫荡指定关卡入口
     *
     * @param roomId    圣殿ID(类型)
     * @param combatNum 第几关（从1开始）
     * @param mop       是否扫荡
     */
    public GameResult<MooncakeChallenge> challenge(int roomId, int combatNum, boolean mop) {
        GameResult<MooncakeChallenge> r = new GameResult<>();
        r.data = this;
        GameResult<Void> challengeRes = challengeCheck(roomId, combatNum, mop);
        if (!challengeRes.ok()) {
            return r.fail(challengeRes);
        }
        MooncakeBossRow combatTpl = role.getGame().table.mooncake.boss.find(roomId, combatNum);
        if (mop) {
            r = mop(combatTpl);
        } else {
            r = challenge(roomId, combatNum, combatTpl);
        }
        return r;
    }

    /**
     * 挑战逻辑
     */
    public GameResult<MooncakeChallenge> challenge(int roomId, int combatNum, MooncakeBossRow tpl) {
        GameResult<MooncakeChallenge> r = new GameResult<>();
        r.data = this;
        this.curRoomId = roomId;

        // 挑战模式
        MooncakeBossRow combatTpl = role.getGame().table.mooncake.boss.find(roomId, combatNum);
        if (combatTpl==null) {
            return r.fail("不存在该关卡");
        }
        String instanceIdStr = combatTpl.monster;

        EcResult<FightSide> fsr = role.getGame().fight.side.createFightSideByCode(GDFight.Team.B, instanceIdStr);

        if (fsr.data == null) {
            return r.fail("策划配置的一方阵容不存在 tpl.instanceId=" + instanceIdStr);
        }
//        ForbiddenFTC context = new ForbiddenFTC(role, tpl, auto);
        MooncakeBossFTC context = new MooncakeBossFTC(role, tpl);
        context.playStory.level = tpl.id;

        //玩家阵容属性加成
//        ForbiddenRoomRow roomRow = role.getGame().table.forbidden.room.get(roomId);

        checkPosition();

        Position position = role.getFight().getPosition(getFuncId());
        if (position == null) {
            return r.fail("挑战阵容不存在");
        }

        if (position.grids.stream().filter(grid -> {
            Hero hero = null;
            if (grid.origin == GDPosition.Origin.BAG) {
                hero = role.getBag().hero.getItem(grid.uid);
            }
            if (hero != null) {
                return hero.getTpl(role.getGame()).camp == tpl.campReq;
            }
            return false;
        }).count() < tpl.campNumReq) {
            return r.fail("上阵英雄不满足条件");
        }
        for (HeroGrid grid : position.grids) {
            Hero hero = null;
            if (grid.origin == GDPosition.Origin.BAG) {
                hero = role.getBag().hero.getItem(grid.uid);
            }
            if (hero == null) {
                continue;
            }
//            log.info("阵营:" + hero.getTpl(role.getGame()).camp);
        }
        // 种族禁地大类型 sub填子类型
        context.funcId = getFuncId();
        context.playStory.subType = roomId;
        EcResult<PlayPO> fightRes = role.getGame().play.startByRole(role, context, fsr.data);
        if (!fightRes.ok()) {
            return r.fail(fightRes.message);
        }
        fighting = true;
        return r.success();
    }

    public void checkPosition() {
        if (role.getFight().funcPositions.get(getFuncId()) == null
                || role.getFight().funcPositions.get(getFuncId()).positions.isEmpty()) {
            Position position = role.getFight().getPosition(ADVENTURE);
            if (position != null) {
                FuncPosition funcPosition = new FuncPosition();
                funcPosition.init();
                funcPosition.funcId = getFuncId();
                funcPosition.positions.add(position.copy());
                role.getGame().fight.position.updatePosition(role, funcPosition);
            }
        }
    }

    /**
     * 扫荡逻辑
     */
    private GameResult<MooncakeChallenge> mop(MooncakeBossRow combatTpl) {
        // 扫荡模式
        GameResult<MooncakeChallenge> r = new GameResult<>();
        r.data = this;
        MixRes reward = new MixRes(combatTpl.passReward);
        reward.addAndDialog(role, true, GDOperation.MOONCAKE_MOP_REWARD);
        playTimes.added();
        this.challengeTimes++;
        role.sendNow(new MooncakeChallengeDataResp(this));
        return r.success();
    }

    public int totalPass() {
        return this.challengeTimes;
    }
}
